from openai import OpenAI
from typing import Dict, Any, List, Optional
import logging
import os

# 配置日志
logger = logging.getLogger(__name__)

# 初始化OpenAI客户端
client = OpenAI(
    api_key="sk-38b9daad5d5e46f690545046695bd6ff",
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

# 用户水平定义
USER_LEVELS = {
    "初学者": {
        "description": "对领域知识了解较少，需要基础概念解释和入门指导",
        "response_style": "详细解释，提供基础概念，使用简单易懂的语言",
        "content_preference": "基础概念、入门教程、简单示例",
        "weights": {"similarity": 0.4, "popularity": 0.3, "credibility": 0.2, "difficulty": -0.1}
    },
    "进阶学习者": {
        "description": "有一定基础，希望深入学习特定技术或方法",
        "response_style": "深入分析，提供技术细节，包含实践建议",
        "content_preference": "技术原理、最佳实践、案例分析",
        "weights": {"similarity": 0.3, "popularity": 0.1, "credibility": 0.3, "difficulty": 0.3}
    },
    "专家级": {
        "description": "在领域内有丰富经验，关注前沿技术和复杂问题",
        "response_style": "专业深入，关注技术细节和前沿发展",
        "content_preference": "前沿技术、复杂问题解决方案、深度分析",
        "weights": {"similarity": 0.2, "popularity": 0.1, "credibility": 0.4, "difficulty": 0.3}
    }
}

# 意图类型定义（针对RAG场景优化）
INTENT_TYPES = {
    "概念解释": {
        "description": "用户希望了解某个概念或术语的解释",
        "keywords": ["什么是", "解释", "概念", "定义", "含义"],
        "weights": {"similarity": 0.5, "popularity": 0.1, "credibility": 0.4, "difficulty": 0.0}
    },
    "技术原理": {
        "description": "用户希望了解技术的工作原理或机制",
        "keywords": ["原理", "机制", "如何工作", "流程", "架构"],
        "weights": {"similarity": 0.4, "popularity": 0.1, "credibility": 0.4, "difficulty": 0.1}
    },
    "实践指导": {
        "description": "用户希望获得实践操作或实施的指导",
        "keywords": ["怎么做", "步骤", "实践", "实施", "操作"],
        "weights": {"similarity": 0.3, "popularity": 0.2, "credibility": 0.3, "difficulty": 0.2}
    },
    "问题解决": {
        "description": "用户遇到问题需要解决方案",
        "keywords": ["问题", "错误", "故障", "解决", "修复"],
        "weights": {"similarity": 0.4, "popularity": 0.1, "credibility": 0.4, "difficulty": 0.1}
    },
    "比较分析": {
        "description": "用户希望比较不同技术或方法",
        "keywords": ["比较", "对比", "区别", "优劣", "选择"],
        "weights": {"similarity": 0.4, "popularity": 0.1, "credibility": 0.4, "difficulty": 0.1}
    },
    "最佳实践": {
        "description": "用户希望了解行业最佳实践或推荐方案",
        "keywords": ["最佳实践", "推荐", "标准", "规范", "建议"],
        "weights": {"similarity": 0.3, "popularity": 0.3, "credibility": 0.3, "difficulty": 0.1}
    },
    "前沿技术": {
        "description": "用户关注最新技术发展或前沿趋势",
        "keywords": ["最新", "前沿", "趋势", "发展", "未来"],
        "weights": {"similarity": 0.3, "popularity": 0.4, "credibility": 0.2, "difficulty": 0.1}
    }
}

class IntentRecognizer:
    """意图识别器"""
    
    @staticmethod
    def recognize_intent(query: str) -> Dict[str, Any]:
        """识别用户意图"""
        prompt = f"""
        请分析以下用户查询，识别用户的主要意图。请从以下几种意图中选择最匹配的一种：

        1. 概念解释：用户希望了解某个概念或术语的解释
        2. 技术原理：用户希望了解技术的工作原理或机制
        3. 实践指导：用户希望获得实践操作或实施的指导
        4. 问题解决：用户遇到问题需要解决方案
        5. 比较分析：用户希望比较不同技术或方法
        6. 最佳实践：用户希望了解行业最佳实践或推荐方案
        7. 前沿技术：用户关注最新技术发展或前沿趋势

        用户查询: {query}

        请只返回一个意图类型的名称，不要有任何其他解释。例如：概念解释
        """
        
        try:
            response = client.chat.completions.create(
                model="qwen-max",
                messages=[{
                    "role": "system",
                    "content": "你是一个精确的意图识别助手，能够准确识别用户查询的意图。"
                }, {
                    "role": "user",
                    "content": prompt
                }],
                temperature=0.1
            )
            
            intent = response.choices[0].message.content.strip()
            
            for intent_type in INTENT_TYPES.keys():
                if intent_type in intent:
                    return {
                        "intent_type": intent_type,
                        "weights": INTENT_TYPES[intent_type]["weights"],
                        "description": INTENT_TYPES[intent_type]["description"]
                    }
            
            # 默认返回概念解释
            return {
                "intent_type": "概念解释",
                "weights": INTENT_TYPES["概念解释"]["weights"],
                "description": INTENT_TYPES["概念解释"]["description"]
            }
        
        except Exception as e:
            logger.error(f"意图识别失败: {e}")
            return {
                "intent_type": "概念解释",
                "weights": INTENT_TYPES["概念解释"]["weights"],
                "description": INTENT_TYPES["概念解释"]["description"]
            }

    @staticmethod
    def recognize_user_level(query: str, conversation_history: Optional[List[Dict]] = None) -> Dict[str, Any]:
        """识别用户水平"""
        # 构建历史对话上下文
        history_context = ""
        if conversation_history:
            recent_messages = conversation_history[-3:]  # 最近3条消息
            history_context = "\n".join([
                f"{msg['role']}: {msg['content'][:100]}..." 
                for msg in recent_messages
            ])
        
        prompt = f"""
        请分析以下用户查询和对话历史，判断用户的专业水平。请从以下三种水平中选择最匹配的一种：

        1. 初学者：对领域知识了解较少，需要基础概念解释和入门指导
        2. 进阶学习者：有一定基础，希望深入学习特定技术或方法
        3. 专家级：在领域内有丰富经验，关注前沿技术和复杂问题

        用户查询: {query}
        
        对话历史:
        {history_context if history_context else "无对话历史"}

        请只返回一个水平等级的名称，不要有任何其他解释。例如：初学者
        """
        
        try:
            response = client.chat.completions.create(
                model="qwen-max",
                messages=[{
                    "role": "system",
                    "content": "你是一个专业的用户水平评估助手，能够准确判断用户的专业水平。"
                }, {
                    "role": "user",
                    "content": prompt
                }],
                temperature=0.1
            )
            
            level = response.choices[0].message.content.strip()
            
            for level_type in USER_LEVELS.keys():
                if level_type in level:
                    return {
                        "user_level": level_type,
                        "response_style": USER_LEVELS[level_type]["response_style"],
                        "content_preference": USER_LEVELS[level_type]["content_preference"],
                        "weights": USER_LEVELS[level_type]["weights"],
                        "description": USER_LEVELS[level_type]["description"]
                    }
            
            # 默认返回进阶学习者
            return {
                "user_level": "进阶学习者",
                "response_style": USER_LEVELS["进阶学习者"]["response_style"],
                "content_preference": USER_LEVELS["进阶学习者"]["content_preference"],
                "weights": USER_LEVELS["进阶学习者"]["weights"],
                "description": USER_LEVELS["进阶学习者"]["description"]
            }
        
        except Exception as e:
            logger.error(f"用户水平识别失败: {e}")
            return {
                "user_level": "进阶学习者",
                "response_style": USER_LEVELS["进阶学习者"]["response_style"],
                "content_preference": USER_LEVELS["进阶学习者"]["content_preference"],
                "weights": USER_LEVELS["进阶学习者"]["weights"],
                "description": USER_LEVELS["进阶学习者"]["description"]
            }

    @staticmethod
    def build_adaptive_prompt(
        query: str, 
        retrieved_chunks: List[str], 
        intent_info: Dict[str, Any],
        user_level_info: Dict[str, Any],
        image_paths: Optional[List[str]] = None
    ) -> str:
        """构建自适应prompt（支持图片信息）"""
        
        intent_type = intent_info.get("intent_type", "概念解释")
        user_level = user_level_info.get("user_level", "进阶学习者")
        response_style = user_level_info.get("response_style", "深入分析，提供技术细节")
        
        # 根据意图和用户水平调整prompt
        if intent_type == "概念解释" and user_level == "初学者":
            system_prompt = f"""你是一个专业的技术助手，专门为{user_level}提供帮助。

回答要求：
- 使用{response_style}
- 提供清晰的概念解释
- 使用简单易懂的语言
- 可以适当使用类比和例子
- 避免过于技术性的术语
- 如果涉及图片内容，请描述图片中的关键信息

请基于以下知识库内容回答用户问题："""
        
        elif intent_type == "技术原理" and user_level == "专家级":
            system_prompt = f"""你是一个专业的技术专家，专门为{user_level}提供深度技术分析。

回答要求：
- 使用{response_style}
- 深入分析技术原理
- 关注技术细节和实现机制
- 可以讨论前沿发展和优化方案
- 提供专业的技术见解
- 如果涉及图片内容，请分析图片中的技术细节

请基于以下知识库内容回答用户问题："""
        
        else:
            system_prompt = f"""你是一个专业的技术助手，专门为{user_level}提供帮助。

回答要求：
- 使用{response_style}
- 根据用户意图提供相应类型的回答
- 平衡技术深度和可理解性
- 提供实用的建议和指导
- 如果涉及图片内容，请结合图片信息进行回答

请基于以下知识库内容回答用户问题："""
        
        # 构建知识库内容
        knowledge_content = "\n\n".join([
            f"知识库内容 {i+1}:\n{chunk}" 
            for i, chunk in enumerate(retrieved_chunks)
        ])
        
        # 构建图片信息
        image_content = ""
        if image_paths:
            image_content = "\n\n=== 相关图片信息 ===\n"
            for i, img_path in enumerate(image_paths):
                filename = os.path.basename(img_path)
                image_content += f"图片 {i+1}: {filename}\n"
            image_content += "\n注意：以上图片与用户问题相关，请在回答中考虑图片内容。"
        
        # 完整prompt
        full_prompt = f"""{system_prompt}

{knowledge_content}{image_content}

用户问题: {query}

请根据用户水平({user_level})和意图({intent_type})提供合适的回答。如果涉及图片内容，请在回答中描述或分析图片中的信息。"""
        
        return full_prompt

    @staticmethod
    def get_adaptive_weights(intent_info: Dict[str, Any], user_level_info: Dict[str, Any]) -> Dict[str, float]:
        """获取自适应权重"""
        intent_weights = intent_info.get("weights", {})
        user_weights = user_level_info.get("weights", {})
        
        # 融合意图和用户水平的权重
        adaptive_weights = {}
        for key in intent_weights.keys():
            if key in user_weights:
                # 简单平均融合
                adaptive_weights[key] = (intent_weights[key] + user_weights[key]) / 2
            else:
                adaptive_weights[key] = intent_weights[key]
        
        return adaptive_weights

    @staticmethod
    def build_direct_qa_prompt(
        query: str,
        intent_info: Dict[str, Any],
        user_level_info: Dict[str, Any]
    ) -> str:
        """构建直接问答模式的prompt（无知识库检索内容时使用）"""
        try:
            intent_type = intent_info.get("intent_type", "概念解释")
            user_level = user_level_info.get("user_level", "初学者")
            
            # 根据意图和用户水平调整回答风格
            style_guide = ""
            if user_level == "初学者":
                style_guide = "请用通俗易懂的语言解释，提供基础概念和入门指导。"
            elif user_level == "进阶学习者":
                style_guide = "请提供深入的技术分析，包含具体的技术细节和实现方法。"
            else:  # 专家级
                style_guide = "请提供专业的技术分析，包含前沿技术和复杂问题的解决方案。"
            
            # 根据意图类型调整回答重点
            intent_guide = ""
            if intent_type == "概念解释":
                intent_guide = "请重点解释相关概念、定义和基本原理。"
            elif intent_type == "技术原理":
                intent_guide = "请重点解释技术的工作原理、机制和核心算法。"
            elif intent_type == "实践指导":
                intent_guide = "请重点提供具体的实践步骤、操作方法和实施建议。"
            elif intent_type == "问题解决":
                intent_guide = "请重点分析问题原因，提供具体的解决方案和步骤。"
            elif intent_type == "比较分析":
                intent_guide = "请重点比较不同技术或方法的优缺点、适用场景。"
            elif intent_type == "最佳实践":
                intent_guide = "请重点介绍行业最佳实践、推荐方案和成功案例。"
            elif intent_type == "前沿技术":
                intent_guide = "请重点介绍最新技术发展、前沿趋势和创新应用。"
            
            prompt = f"""
            你是一个专业的AI助手，请根据用户的专业水平和意图类型，提供准确、有用的回答。

            用户问题: {query}
            用户水平: {user_level}
            查询意图: {intent_type}

            回答要求:
            1. {style_guide}
            2. {intent_guide}
            3. 如果问题涉及技术细节，请提供具体的技术说明
            4. 如果问题需要实践指导，请提供可操作的步骤
            5. 如果问题涉及比较分析，请客观分析各方案的优缺点
            6. 如果问题超出你的知识范围，请诚实说明并提供相关建议

            请提供详细、准确的回答。
            """
            
            return prompt
            
        except Exception as e:
            logger.error(f"构建直接问答prompt失败: {e}")
            # 返回简单的prompt作为fallback
            return f"""
            请回答用户的问题：

            用户问题: {query}

            请提供准确、有用的回答。
            """ 